package MyDoubleLinkedList;

public class MyDoubleLinkedList implements Operations{
    public Node headNode;

    public int size;

    @Override
    public void addFirst(int data) {
        Node node = new Node(data);

        if (this.size == 0) {
            headNode = node;
            this.size++;
            return;
        }

        headNode.prevNode = node;
        node.nextNode = headNode;
        headNode = node;
        this.size++;
    }

    @Override
    public void addLast(int data) {
        Node node = new Node(data);

        if (this.size == 0) {
            this.addFirst(data);
            return;
        }

        Node curNode = headNode;

        while (curNode.nextNode != null) {
            curNode = curNode.nextNode;
        }

        curNode.nextNode = node;
        node.prevNode = curNode;
        this.size++;
    }

    @Override
    public void addIndex(int index, int data) {
        if (index < 0 || index > this.size) {
            throw new IndexException("下标不合法");
        }

        if (index == 0) {
            this.addFirst(data);
            return;
        } else if (index == this.size) {
            this.addLast(data);
            return;
        }

        Node curNode = headNode;

        while (index != 0) {
            curNode = curNode.nextNode;
            index--;
        }

        Node prevNode = curNode.prevNode;

        Node node = new Node(data);

        node.nextNode = curNode;
        node.prevNode = prevNode;
        prevNode.nextNode = node;
        curNode.prevNode = node;
        this.size++;
    }

    @Override
    public boolean contains(int key) {
        if (this.size == 0) {
            System.out.println("链表为空");
            return false;
        }

        Node curNode = headNode;

        while (curNode != null) {
            if (curNode.val == key) {
                return true;
            }
            curNode = curNode.nextNode;
        }

        return false;
    }

    @Override
    public void remove(int key) {

        if (this.size == 0) {
            System.out.println("链表为空");
            return;
        }

        if (!this.contains(key)) {
            System.out.println("链表不包含该元素");
            return;
        }

        Node curNode = headNode;

        while (curNode != null) {
            if (curNode.val == key) {
                break;
            }
            curNode = curNode.nextNode;
        }

        if (curNode.prevNode == null) { //是头节点
            this.headNode = headNode.nextNode;
            if (this.headNode != null) {
                this.headNode.prevNode = null;
            }
        } else if (curNode.nextNode == null) { //是尾结点
            curNode.prevNode.nextNode = null;
        } else {
            curNode.prevNode.nextNode = curNode.nextNode;
            curNode.nextNode.prevNode = curNode.prevNode;
            curNode = null;
        }

        this.size--;
    }

    @Override
    public void removeAllKey(int key) {
        if (this.size == 0) {
            System.out.println("链表为空");
            return;
        }

        if (!this.contains(key)) {
            System.out.println("链表不包含该元素");
            return;
        }

        Node curNode = headNode;

        while (curNode != null) {
            if (curNode.val == key) {
                if (curNode.prevNode == null) { //是头节点
                    this.headNode = headNode.nextNode;
                    if (this.headNode != null) {
                        this.headNode.prevNode = null;
                    } else {
                        break;
                    }
                } else if (curNode.nextNode == null) { //是尾结点
                    curNode.prevNode.nextNode = null;
                } else {
                    curNode.prevNode.nextNode = curNode.nextNode;
                    curNode.nextNode.prevNode = curNode.prevNode;
                }
            }
            curNode = curNode.nextNode;
        }
        this.size = 0;
    }

    @Override
    public int size() {
        return this.size;
    }

    @Override
    public void display() {
        Node curNode = headNode;

        while (curNode != null) {
            System.out.print(curNode.val + " ");
            curNode = curNode.nextNode;
        }
        System.out.println();
    }

    @Override
    public void clear() {
        while (headNode != null) {
            Node next = headNode.nextNode;
            headNode = null;
            headNode = next;
        }
    }
}
